package com.rankeiot.platform.service;

import com.rankeiot.core.data.UserInfo;
import com.rankeiot.core.event.LogEvent;
import com.rankeiot.platform.domain.OperationLog;
import lombok.RequiredArgsConstructor;

import org.sagacity.sqltoy.dao.SqlToyLazyDao;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 用户日志
 * @author desire
 */
@Component
@RequiredArgsConstructor
public class OperationLogService {
    private final int batchSize = 200;
    private List<OperationLog> tempLogs = new ArrayList<>(batchSize);

    final SqlToyLazyDao dao;

//    public OperationLogService() {
//        /**
//         * 保存间隔
//         */
//        int saveInterval = 10;
//       // Utils.scheduled.scheduleAtFixedRate(this, saveInterval, saveInterval, TimeUnit.SECONDS);
//       // RunUtil.delayAndRepeat(this,saveInterval*1000);
//    }


    @EventListener
    public void onEvent(LogEvent e) throws Throwable {
        saveLogs(false);
        OperationLog log = new OperationLog();
        com.rankeiot.core.anno.OperationLog anno = e.getLog();
        log.setOperate(anno.value());
        log.setOperateType(anno.operateType().name());
        log.setModule(anno.module());
//
//        Context ctx = e.getCtx();
//        log.setPath(ctx.path());
//        log.setIp(ctx.realIp());
//        log.setQuery(ctx.queryString());
        log.setCreateTime(new Date());
//        if(anno.saveBody()){
//            log.setBody(ctx.body());
//        }
        log.setIp(e.getIp());
        log.setPath(e.getPath());
        log.setQuery(e.getQuery());
       // log.setBody(e.getBody());
        UserInfo userInfo = e.getUserInfo();
        if (userInfo != null) {
            log.setUser(userInfo.getUsername());
            log.setUserType(userInfo.getUserType()+"");
        }
        if(e.getError()==null){
            log.setStatus("success");
        }else{
            log.setStatus("fail");
        }
        tempLogs.add(log);
    }


    @Scheduled(fixedDelay = 30000)
    public void doSave() {
        saveLogs(true);
    }

    private void saveLogs(boolean direct) {
        List<OperationLog> logs;
        synchronized (this) {
            int size=tempLogs.size();
            if (size == 0) {
                return;
            }
            if (dao == null) {
                return;
            }
            if(!direct){
               if(size<batchSize){
                   return;
               }
            }
            logs = tempLogs;
            tempLogs = new ArrayList<>(batchSize);
        }
        dao.saveAll(logs);
    }
}
